<template>
  <div
    :style="circleSize"
    :class="wrapClasses"
  >
    <svg viewBox="0 0 100 100">
      <defs v-if="showDefs">
        <linearGradient
          :id="id"
          x1="100%"
          y1="0%"
          x2="0%"
          y2="0%"
        >
          <stop
            offset="0%"
            :stop-color="strokeColor[0]"
          />
          <stop
            offset="100%"
            :stop-color="strokeColor[1]"
          />
        </linearGradient>
      </defs>
      <path
        :d="pathString"
        :stroke="trailColor"
        :stroke-width="trailWidth"
        :fill-opacity="0"
        :style="trailStyle"
        :stroke-linecap="strokeLinecap"
      />
      <path
        :d="pathString"
        :stroke-linecap="strokeLinecap"
        :stroke="strokeValue"
        :stroke-width="computedStrokeWidth"
        fill-opacity="0"
        :style="pathStyle"
      />
    </svg>
    <div :class="innerClasses">
      <slot />
    </div>
  </div>
</template>
<script>
import { oneOf } from '../../utils/assist'
import random from '../../utils/random_str'

const prefixCls = 'ivu-chart-circle'

export default {
  name: 'ICircle',
  props: {
    percent: {
      type: Number,
      default: 0
    },
    size: {
      type: Number,
      default: 120
    },
    strokeWidth: {
      type: Number,
      default: 6
    },
    strokeColor: {
      type: [String, Array],
      default: '#2d8cf0'
    },
    strokeLinecap: {
      validator (value) {
        return oneOf(value, ['square', 'round'])
      },
      default: 'round'
    },
    trailWidth: {
      type: Number,
      default: 5
    },
    trailColor: {
      type: String,
      default: '#eaeef2'
    },
    dashboard: {
      type: Boolean,
      default: false
    }
  },
  data () {
    return {
      id: `ivu-chart-circle-${random(3)}`
    }
  },
  computed: {
    circleSize () {
      return {
        width: `${this.size}px`,
        height: `${this.size}px`
      }
    },
    computedStrokeWidth () {
      return this.percent === 0 && this.dashboard ? 0 : this.strokeWidth
    },
    radius () {
      return 50 - this.strokeWidth / 2
    },
    pathString () {
      if (this.dashboard) {
        return `M 50,50 m 0,${this.radius}
                    a ${this.radius},${this.radius} 0 1 1 0,-${2 * this.radius}
                    a ${this.radius},${this.radius} 0 1 1 0,${2 * this.radius}`
      } else {
        return `M 50,50 m 0,-${this.radius}
                    a ${this.radius},${this.radius} 0 1 1 0,${2 * this.radius}
                    a ${this.radius},${this.radius} 0 1 1 0,-${2 * this.radius}`
      }
    },
    len () {
      return Math.PI * 2 * this.radius
    },
    trailStyle () {
      let style = {}
      if (this.dashboard) {
        style = {
          'stroke-dasharray': `${this.len - 75}px ${this.len}px`,
          'stroke-dashoffset': `-${75 / 2}px`,
          transition: 'stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s'
        }
      }
      return style
    },
    pathStyle () {
      let style = {}
      if (this.dashboard) {
        style = {
          'stroke-dasharray': `${(this.percent / 100) * (this.len - 75)}px ${this.len}px`,
          'stroke-dashoffset': `-${75 / 2}px`,
          transition: 'stroke-dashoffset .3s ease 0s, stroke-dasharray .6s ease 0s, stroke .6s, stroke-width .06s ease .6s'
        }
      } else {
        style = {
          'stroke-dasharray': `${this.len}px ${this.len}px`,
          'stroke-dashoffset': `${((100 - this.percent) / 100 * this.len)}px`,
          transition: 'stroke-dashoffset 0.6s ease 0s, stroke 0.6s ease'
        }
      }
      return style
    },
    wrapClasses () {
      return `${prefixCls}`
    },
    innerClasses () {
      return `${prefixCls}-inner`
    },
    strokeValue () {
      let color = this.strokeColor
      if (typeof this.strokeColor !== 'string') {
        color = `url(#${this.id})`
      }
      return color
    },
    showDefs () {
      return typeof this.strokeColor !== 'string'
    }
  }
}
</script>
